---
title: "Vim undo trees"
date:  2019-01-10
category:  TechTips
---

On a recent refactoring binge, after plodding and slashing through the knots
and duplication and inelegances of a first draft, I had accidentally
conflated 2 objects, thinking I was referring to the same thing by two
different names, and gleeful to reduce clutter and enhance the clarity of
the code, I replaced all instances of mac_addr with uuid.  And then my code
promptly stopped working.  And since I'd done the replacement in a manual-ish,
and not entirely atomic way, it was more difficult than it should have been to
revert the code to its earlier, working state.

Blast!@

(note: I was able to use the exact technique that I am currently halfway
through writing about, for only the second time ever, in order to recover
the line directly above this note.)

I had made several edits, and then wanted to undo them, so I began backing up
the undo stack (i.e., just mashing the u key in normal mode), but then
accidentally added some new text, partway up the stack.  This was a mistake, but
when I re-entered normal mode to again move up the undo stack, my possibilities
for regression stopped at the beginning of the accidental changes.

Repeated presses of the undo key did not recover these earlier changes.  My
buffer remain fixed in a state represented as the first node in a "new
branch" of changes that I had created accidentally by entering insert mode
at the wrong time.  Wrong mode, wrong time.  This was frustrating and a bit
stressful.

So I thought, roughly, 'wait, there must be a feature like this in vim'.  And
there was.  And I'd never used it (actually I had used it, but hadn't quite
realized what I was using).  Then it became immediately useful to me.  Again,
further into this article I've had opportunity to use it a third time.  It's
a feature that is simple, powerful, and comforting when writing complex
documents.

I'll keep you in suspense no longer, gentle reader.  The secret incantations
are:

`g-` and `g+`

or equivalently

`:earlier` and `:later`

to move backward and forward through the undo list via a tree structure,
rather than a list / linear, manner.  In other words, you can have undo
trees, rather than undo sequences or lists.

You can also move in larger increments than a single step.  You can move back
and forward using a count (i.e., a number of edits) or a time incremement.  For
example, you can move back 1 hour, or forward 10 edits, as follows:

`:earlier 1h` 

or 

`:later 10`

To see how many edits you've made in your currently active buffer, you can use
the `echo changenr()` command.  This can be useful if you are trying to find
your way through a complex set of changes and undos/redos.

For more information about this feature, as well as the related persistent undo
feature, (i.e., an undo history that is saved across editing sessions), check
out [this page](http://vim.wikia.com/wiki/Using_undo_branches).

## Conclusion

Looking for a solution to this problem, when it arose in my everyday usage, led
me to find, already thought-through and built, a more sophisticated model of
edit history than the one I had heretofore been using to operate the vim editor.
I am continually impressed and humbled by the intelligence and labour that has
gone into this tool.  After three years of intensive usage and study of vim,
I am still learning about its capabilities.

In [another blog post](terror_of_prototypes.html) I discuss the human side
behind this discovery, the terror of working with prototypes and hardware, and
my appreciation for vim.
